/**
 * 是否字符串
 * @param {入参} str
 * @returns Boolean
 */
export const isString = (str) => typeof str === 'string'

/**
 * 是否为对象
 * @params {入参} obj
 * @returns Boolean
 */
export const isObject = (obj) => Object.prototype.toString.call(obj) === '[object Object]'

/**
 * 是否为空对象
 * @params {入参} obj
 * @returns Boolean
 */
export const isEmptyObject = (obj) => isObject(obj) ? !!Object.keys(obj).length : false

/**
 * 是否为数组
 * @param {入参} arr
 * @returns Boolean
 */
export const isArray = (arr) => Array.isArray(arr)

/**
 * 两数组的指定长度的内容是否相同
 * @param {数组1} arr1
 * @param {数组2} arr2
 * @param {长度} length
 */
export const isTheSameBefore = (arr1, arr2, length) => isArray(arr1) && isArray(arr2) ? JSON.stringify(arr1.slice(0, length)) === JSON.stringify(arr2.slice(0, length)) : false

/**
 * 是否16进制颜色和rgba颜色
 * @param {颜色字符串} str
 * @returns Boolean
 */
export const isColor = (str) => {
  if (isString(str)) {
    return (
      str.match(/^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/g) !== null ||
      str.match(
        /^[rR][gG][Bb][Aa]?[\(]([\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?),){2}[\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?),?[\s]*(0\.\d{1,2}|1|0)?[\)]{1}$/g
      ) !== null
    )
  } else {
    return false
  }
}

/**
 * 字符串中指定子字符串高亮且大小写不敏感
 * @param {需要被高亮的字符串} str
 * @param {高亮字符串} sonStr
 * @param {高亮颜色} color
 * @returns String
 */
export const makeHighLight = (str, sonStr, color = '#3693FF') => {
  if (!isString(str) || !isString(sonStr) || !isColor(color)) return str
  const reg = new RegExp(sonStr, 'gi')
  return str.replace(reg, match => {
    return `<span style="color: ${color};overflow: hidden">${match}</span>`
  })
}

/**
   * 给图片添加水印
   * @param {*} obj
   * @returns Promise
   */
export const watermarkImage = ({
    base64OrImgPath, // 图片地址或者是base64数据
    repetitionsRow = 3, // 水印重复行数
    repetitionsCol = 4, // 水印重复列数
    rotate = 20, // 顺时针旋转监督
    font = '400 10px Arial', // 水印文字的字体
    fillStyle = 'rgba(255, 255, 255, 0.5)', // 水印文字的填充样式
    content = '水印' // 水印文字的内容
  }) => {
    const image = new Image()
    image.src = base64OrImgPath
    return new Promise((resolve, reject) => {
      image.onload = () => {
        console.log('image.width:', image.width, image.height)
        const canvas = document.createElement('canvas')
        canvas.width = image.width
        canvas.height = image.height
        const ctx = canvas.getContext('2d')
        ctx.drawImage(image, 0, 0, image.width, image.height)
        // ctx.fillText('水印xxx', 10, 10)
        // 添加旋转的水印多次
        for (let i = 0; i < repetitionsRow * repetitionsCol; i++) {
          // 计算水印位置
          const x = (i % repetitionsRow) * (image.width / repetitionsRow) + 10
          const y = Math.floor(i / repetitionsCol) * (image.height / repetitionsCol) + 10

          // 保存当前状态
          ctx.save()

          // 旋转Canvas上下文
          ctx.translate(x, y) // 移动到水印文本的起始位置
          ctx.rotate((rotate * Math.PI) / 180) // 旋转45度

          // 设置字体样式
          ctx.font = font // 设置字体样式
          ctx.fillStyle = fillStyle // 设置水印颜色（半透明白色）

          // 绘制水印文本
          ctx.fillText(content, 0, 0)

          // 恢复Canvas上下文状态
          ctx.restore()
        }
        const watermarkedImageUrl = canvas.toDataURL('image/png') // 转换为PNG格式图片
        resolve(watermarkedImageUrl)
      }
      image.onerror = () => {
        reject(new Error('Failed to load image'))
      }
    })
  }

/**
 * 
 * @param {提示信息} msg 
 * @param {持续时间} duration 
 */
export const fadeInOut = (msg, duration = 3000) => {
  if (msg == "" || msg == null) {
    msg = "提示！";
  }
  const durationTime = isNaN(duration) ? 3000 : duration;
  let time = null;
  let time1 = null;
  const msgStyle =
    "display:block;position: fixed;width: 100%;top: 50%;margin-top: 24px;text-align: center;line-height: 24px;z-index: 99999;font-size: 16px;text-align: center;";
  const spanStyle =
    "opacity: 0.6;border-radius: 4px;color: #fff;padding: 6px 15px;display: inline-block;background:rgba(0, 0, 0, 1)";
  const div = document.createElement("div");
  div.innerHTML = `<span id="hh">` + msg + "</span>";
  div.setAttribute("id", "msg")
  div.setAttribute("style", msgStyle);
  document.body.appendChild(div);
  document.getElementById("hh").setAttribute("style", spanStyle);
  let num = 0;
  const step = 40;
  clearInterval(time);
  clearInterval(time1);
  time = setInterval(function() {
    num += step;
    if (num >= 360) {
      num = 360;
      clearInterval(time);
      setTimeout(function() {
        time1 = setInterval(function() {
          num -= step;
          if (num == 0) {
            num = 0;
            clearInterval(time1);
            document.body.removeChild(document.getElementById("msg"));
          }
        }, 40);
      }, durationTime);
    }
  }, 40);
}

/**
 * 2022-10-10 12:00:00初始化date对象时IOS不能将转换，故将其转换为2022/10/10 12:00:00方能初始化
 * @param {时间字符串} timeStr
 * @returns Date
 */
export const getDateInstanceFromStr = (timeStr) => {
    if (isString(timeStr)) {
        return new Date(timeStr.replace(/-/g, "/"));
    } else {
        return null;
    }
}

/**
 * 实现指定元素的悬浮拖拽
 * @param {html元素} element 
 */
export const dragAction = element => {
  element.style.position = "fixed";
  let startX = 0;
  let startY = 0;
  // 获取盒子原先的位置
  let x = 0;
  let y = 0;
  element.addEventListener("touchstart", function(e) {
    //获取手指初始坐标
    startX = e.targetTouches[0].pageX;
    startY = e.targetTouches[0].pageY;
    // 获取盒子原先的位置
    x = this.offsetLeft;
    y = this.offsetTop;
  });
  element.addEventListener("touchmove", function(e) {
    // 计算手指的移动距离：手指移动之后的坐标减去手指初始的坐标
    const moveX = e.targetTouches[0].pageX - startX;
    const moveY = e.targetTouches[0].pageY - startY;
    // y移动盒子
    this.style.left = x + moveX + "px";
    this.style.top = y + moveY + "px";
    e.preventDefault(); //阻止屏幕滚动的默认行为
  });
}
/**
 * 实现指定元素的全屏
 * @param {dom} ele
 */
export const fullScreen = (ele = document.documentElement) => {
    ele.requestFullscreen && ele.requestFullscreen();
    ele.mozRequestFullScreen && ele.mozRequestFullScreen();
    ele.webkitRequestFullscreen && ele.webkitRequestFullscreen();
    ele.msRequestFullscreen && ele.msRequestFullscreen();
}

/**
 * 退出全屏
 */
export const exitFullScreen = () => {
    document.exitFullScreen && document.exitFullScreen();
    document.mozCancelFullScreen && document.mozCancelFullScreen();
    document.webkitExitFullscreen && document.webkitExitFullscreen();
    document.msExitFullscreen && document.msExitFullscreen();
}
/**
 * 是否Mac系统
 */
  export const isMac = ()=> {
    return /macintosh|mac os x/i.test(navigator.userAgent)
  }

/**
 * 处理字符串
 * '1133444...8西方00089'
 */
export const handleString = (str = '', startLength = 5, endLength = 7) => {
    const SL = startLength * 2,
      EL = endLength * 2
    // 反转字符串
    const reverseString = str1 =>
      str1
        .split('')
        .reverse()
        .join('')
    // 计算字符串长度(中文字符算两个英文字符)
    const computedLength = strTempArr =>
      strTempArr.reduce((pre, cur) => {
        if (cur.charCodeAt(0) < 256) {
          return pre + 1
        } else {
          return pre + 2
        }
      }, 0)
    // 截取中文字符长度的字符串
    const subChineseLengthString = (s, cl) => {
      const sArr = s.split('')
      const arr = []
      for (let i = 0; i < sArr.length; i++) {
        if (sArr[i].charCodeAt(0) < 256) {
          cl--
          arr.push(sArr[i])
        } else {
          cl -= 2
          arr.push(sArr[i])
        }
        if (cl <= 0) {
          break
        }
      }
      return arr.join('')
    }
    if (computedLength(str.split('')) <= SL + EL) {
      return str
    } else {
      // 中文截取中文字符长度的字符串 + 反转字符串后再截取
      return subChineseLengthString(str, SL) + '...' + reverseString(subChineseLengthString(reverseString(str), EL))
    }
  }